﻿using DXBase;
using DXBase.D3D;
using DXBase.Scenes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace DXBase.XAML
{
	public class ScenePanel : SwapChainBackgroundPanel
	{
		public ScenePanel()
		{
			Context = new DXContext();
			Target = new DXTargetSwapPanelOrWindow(this);

			PerformanceTimer = new PerformanceTimer();
			InputController = new InputController();

			Loaded += delegate
			{
				IsLoaded = true;
				if (InputController != null)
					InputController.CoreWindow = CoreWindow.GetForCurrentThread();
				CompositionTarget.Rendering += OnUIRendering;
			};
			Unloaded += delegate
			{
				IsLoaded = false;
				if (InputController != null)
					InputController.CoreWindow = null;
				CompositionTarget.Rendering -= OnUIRendering;
			};
		}

		public DXTargetSwapPanelOrWindow Target { get; private set; }
		public DXContext Context { get; private set; }
		public bool IsLoaded { get; private set; }
		public PerformanceTimer PerformanceTimer { get; private set; }
		public InputController InputController { get; private set; }

		void OnUIRendering(object sender, object e)
		{
			if (!IsLoaded || Scene == null)
				return;

			Context.Target = Target;

			PerformanceTimer.Update();
			Scene.Update(Context, PerformanceTimer);

			Context.Rendering = true;
			try
			{
				Scene.Render(Context);
			}
			finally { Context.Rendering = false; }
		}

		public IScene Scene
		{
			get { return (IScene)GetValue(SceneProperty); }
			set { SetValue(SceneProperty, value); }
		}
		public static readonly DependencyProperty SceneProperty = DependencyProperty.Register(
			"Scene", 
			typeof(IScene), 
			typeof(ScenePanel), 
			new PropertyMetadata(null, (o, e)=>((ScenePanel)o).OnSceneChanged((IScene)e.OldValue, (IScene)e.NewValue)));

		private void OnSceneChanged(IScene sOld, IScene sNew)
		{
			if (sOld != null)
				sOld.Inputcontroller = null;
			if (sNew != null)
				sNew.Inputcontroller = InputController;
		}
	}
}
